package de.hft_stuttgart.dsa.ctt.processing;

import java.util.Map;

import de.hft_stuttgart.dsa.ctt.model.Course;
import de.hft_stuttgart.dsa.ctt.model.CourseAvailabilityMatrix;
import de.hft_stuttgart.dsa.ctt.model.CourseCompetitionMatrix;
import de.hft_stuttgart.dsa.ctt.model.CourseLectureCompetitionMatrix;
import de.hft_stuttgart.dsa.ctt.model.Period;
import de.hft_stuttgart.dsa.ctt.model.ProblemInstance;
import de.hft_stuttgart.dsa.ctt.model.UnavailabilityConstraint;

public class Preprocessor {
	private ProblemInstance problemInstance;
	private CourseAvailabilityMatrix courseAvailabilityMatrix;
	private CourseCompetitionMatrix courseCompetitionMatrix;
	private CourseLectureCompetitionMatrix courseLectureCompetitionMatrix;

	public Preprocessor(ProblemInstance problemInstance, CourseAvailabilityMatrix courseAvailabilityMatrix) {
		super();
		this.problemInstance = problemInstance;
		this.courseAvailabilityMatrix = courseAvailabilityMatrix;
	}

	public Preprocessor(ProblemInstance problemInstance, CourseCompetitionMatrix courseCompetitionMatrix) {
		super();
		this.problemInstance = problemInstance;
		this.courseCompetitionMatrix = courseCompetitionMatrix;
	}

	public Preprocessor(ProblemInstance problemInstance, CourseLectureCompetitionMatrix courseLectureCompetitionMatrix) {
		super();
		this.problemInstance = problemInstance;
		this.courseLectureCompetitionMatrix = courseLectureCompetitionMatrix;
		
	}
	
	public void processCourseCompetitionMatrix() {
		int periodsPerDay = problemInstance.getPeriodsPerDay();

		// first pre-processing step is to assign a number of how many courses
		// can be assigned within a timeslot
		Map<String, Course> entries = problemInstance.getAllCourses();
		for (Course course : entries.values()) {
			for (UnavailabilityConstraint constraint : course.getUnavailabilityConstraints()) {
				int unavailabilityPeriod = Period.getCalculatedPeriod(periodsPerDay, constraint.getPeriodOfDay(), constraint.getDayOfWeek());
				courseCompetitionMatrix.updateSingleTimeslot(unavailabilityPeriod);
			}
		}
	}

	public void processCourseLectureCompetitionMatrix() {
		int periodsPerDay = problemInstance.getPeriodsPerDay();

		// first pre-processing step is to assign a number of how many lectures
		// can be assigned within a timeslot
		Map<String, Course> entries = problemInstance.getAllCourses();
		for (Course course : entries.values()) {
			for (UnavailabilityConstraint constraint : course.getUnavailabilityConstraints()) {
				int unavailabilityPeriod = Period.getCalculatedPeriod(periodsPerDay, constraint.getPeriodOfDay(), constraint.getDayOfWeek());
				courseLectureCompetitionMatrix.updateSingleTimeslot(unavailabilityPeriod, course.getNumberOfLectures());
			}
		}
		
	}

	public void processCourseAvailabilityMatrix() {
		int periodsPerDay = problemInstance.getPeriodsPerDay();

		// first pre-processing step is to...
		Map<String, Course> entries = problemInstance.getAllCourses();
		for (Course course : entries.values()) {
			for (UnavailabilityConstraint constraint : course.getUnavailabilityConstraints()) {
				courseAvailabilityMatrix.updateExceptThisOne(Period.getCalculatedPeriod(periodsPerDay, constraint.getPeriodOfDay(), constraint.getDayOfWeek()));
			}
		}
	}
	
	public ProblemInstance getProblemInstance() {
		return problemInstance;
	}

	public CourseAvailabilityMatrix getCourseAvailabilityMatrix() {
		return courseAvailabilityMatrix;
	}

	public CourseCompetitionMatrix getCourseCompetitionMatrix() {
		return courseCompetitionMatrix;
	}

}